
#include "unixhead.h"   //1. 自定义头文件

//#include <stdio.h>    //2. C的头文件

#include <vector>
#include <iostream>     //3. C++的头文件

//4. 第三方库头文件
#include <workflow/WFFacilities.h>
#include <workflow/WFTaskFactory.h>
#include <workflow/HttpMessage.h>
#include <workflow/HttpUtil.h>

using namespace std;

static WFFacilities::WaitGroup waitGroup(1);

void sighandler(int signum)
{
    cout << "wait group done\n";
    (void)signum;
    waitGroup.done();
}

void parallelCallback(const ParallelWork *)
{
    cout << ">> parallelWork callback is running\n";
}

void parallelSeriesCallback(const SeriesWork * series)
{
    cout << "parallelSeries callback is running\n";
}

void httpCallback(WFHttpTask * httpTask);

void seriesWorkCallback(const SeriesWork * series)
{
    cout << "httpTask Series callback is running\n";
}

void test0()
{
    signal(SIGINT, sighandler);

    auto parallelWork = Workflow::create_parallel_work(parallelCallback);
    vector<string> webs{
        "http://localhost",
        "http://localhost:8082",
        "http://localhost:8081"
    };

    for(size_t idx = 0; idx < webs.size(); ++idx) {
        auto httpTask = WFTaskFactory::create_http_task(webs[idx], 0, 0, httpCallback);
        //设置任务的属性
        auto req = httpTask->get_req();
        req->set_method("GET");
        req->add_header_pair("Accept", "*/*");
        req->add_header_pair("User-Agent", "Workflow client");
        //创建一个序列, 并不提交给框架运行
        auto seriesWork = Workflow::create_series_work(httpTask, seriesWorkCallback);

        //将序列加入到并行任务中
        parallelWork->add_series(seriesWork);
    }
    //将并行任务添加到一个序列中，然后交给框架去运行
    Workflow::start_series_work(parallelWork, parallelSeriesCallback);

    waitGroup.wait();//阻塞当前进程
}


int main()
{
    test0();
    return 0;
}

void httpCallback(WFHttpTask * httpTask)
{
    cout << ">> httpTask callback is running\n";
    auto req = httpTask->get_req();
    auto resp = httpTask->get_resp();

    int state = httpTask->get_state();
    int error = httpTask->get_error();
    switch(state){
    case WFT_STATE_SYS_ERROR:
        fprintf(stderr, "system error: %s\n", strerror(error)); break;
    case WFT_STATE_DNS_ERROR:
        fprintf(stderr, "dns error: %s\n", gai_strerror(error)); break;
    case WFT_STATE_SUCCESS:
        break;
    }

    if(state != WFT_STATE_SUCCESS) {
        printf("error occurs!\n");
        return;
    }

    printf("%s %s %s\n", req->get_method(), 
           req->get_request_uri(),
           req->get_http_version());

    protocol::HttpHeaderCursor cursor(req);
    std::string key, value;
    while(cursor.next(key, value)) {
        cout << key << ":" << value << endl;
    }
    cout << endl;

    //响应报文
    printf("%s %s %s\n", resp->get_http_version(),
           resp->get_status_code(),
           resp->get_reason_phrase());

    protocol::HttpHeaderCursor cursor2(resp);
    while(cursor2.next(key, value)) {
        cout << key << ":" << value << endl;
    }
    cout << endl;

    const void * body;
    size_t sz;
    resp->get_parsed_body(&body, &sz);
    fwrite(body, 1, sz, stdout);
    fflush(stdout);
}
